package cn.bytets.rpc.api.message;

import cn.bytets.rpc.api.InvokeMode;
import cn.bytets.rpc.api.invoke.Invocation;
import cn.bytets.rpc.api.invoke.Invoker;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * 传递的数据
 */
public class RpcInvocation implements Invocation,Serializable {

    public String methodName;
    /**
     * 调用方面的入参类型
     */
    private Class<?>[] parameterTypes;
    /**
     * 调用方法的入参值
     */
    private Object[] arguments;
    /**
     * 特殊字段（包括接口名称,Token等等自定义字段）
     */
    private Map<String, String> attachments;

    private String interfaceName;

    private transient Invoker<?> invoker;

    private transient InvokeMode invokeMode;

    public String getInterfaceName() {
        return interfaceName;
    }

    public void setInterfaceName(String interfaceName) {
        this.interfaceName = interfaceName;
    }

    public RpcInvocation(){}

    public RpcInvocation(String methodName,
                         Class<?>[] parameterTypes,
                         Object[] arguments,String intfName,
                         Invoker<?> invoker,
                         InvokeMode invokeMode){
        this(methodName,parameterTypes,arguments,intfName);
        this.invoker = invoker;
        this.invokeMode = invokeMode;
    }

    public RpcInvocation(String methodName,
                         Class<?>[] parameterTypes,
                         Object[] arguments,String intfName){
        this.methodName = methodName;
        this.parameterTypes = null==parameterTypes?new Class<?>[0]:parameterTypes;
        this.arguments = null==arguments?new Object[0]:arguments;
        this.interfaceName = intfName;
    }
    public void setAttachment(String key, String value) {
        if (attachments == null) {
            attachments = new HashMap<String, String>();
        }
        attachments.put(key, value);
    }

    @Override
    public void setAttachmentIfAbsent(String key, String value) {
        attachments.putIfAbsent(key,value);
    }

    /**
     * get attachment by key.
     *
     * @param key
     * @return attachment value.
     * @serial
     */
    @Override
    public String getAttachment(String key) {
        return attachments.get(key);
    }

    /**
     * get attachment by key with default value.
     *
     * @param key
     * @param defaultValue
     * @return attachment value.
     * @serial
     */
    @Override
    public String getAttachment(String key, String defaultValue) {
        return attachments.getOrDefault(key,defaultValue);
    }

    /**
     * get the invoker in current context.
     *
     * @return invoker.
     * @transient
     */
    @Override
    public Invoker<?> getInvoker() {
        return null;
    }

    public String getMethodName() {
        return methodName;
    }

    public void setMethodName(String methodName) {
        this.methodName = methodName;
    }

    public Class<?>[] getParameterTypes() {
        return parameterTypes;
    }

    public void setParameterTypes(Class<?>[] parameterTypes) {
        this.parameterTypes = parameterTypes;
    }

    public Object[] getArguments() {
        return arguments;
    }

    public void setArguments(Object[] arguments) {
        this.arguments = arguments;
    }

    public Map<String, String> getAttachments() {
        return attachments;
    }

    public void setAttachments(Map<String, String> attachments) {
        this.attachments = attachments;
    }
}
